package projorientado;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Vector;

import javax.imageio.ImageIO;

import projorientado.anpr.OCRPlate;
import projorientado.anpr.PlateRecognitionResult;
import projorientado.anpr.PlateRecognizer;
import projorientado.anpr.impl.BPlateRecognizer;
import projorientado.anpr.impl.BPlateRecognizerBlock;
import projorientado.anpr.impl.BPlateRecognizerProps;
import projorientado.anpr.impl.FormatedOCRPlate;
import projorientado.image.ImageLayerData;
import projorientado.ocr.OCRecognizer;
import projorientado.ocr.impl.AlphabetChar;
import projorientado.ocr.impl.SimpleRecognizer;
import projorientado.ocr.vfeature.FeaturesComparator;
import projorientado.ocr.vfeature.FeaturesExtractor;
import projorientado.ocr.vfeature.FeaturesPairExtractor;
import projorientado.ocr.vfeature.impl.ImageFeaturesComparator;
import projorientado.ocr.vfeature.impl.ImagePairExtractor;
import projorientado.ocr.vfeature.impl.comparator.EuclideanComparator;

public class Main {

    public static void main(String[] args) throws Exception {
        String alphabetDir = new File("alphabet_10x16_bw").getAbsolutePath();
        String debugVisitorDir = new File("segs").getAbsolutePath();
        
        // RECONHECEDORES
        
        OCRecognizer ocr = createOCRecognizer(alphabetDir,debugVisitorDir);
        FormatedOCRPlate ocrp = new FormatedOCRPlate(ocr,"AAA 0000");
        PlateRecognizer anpr = createBRPlateRecognizer(ocrp);
        
        // CARREGAR IMAGEM
        
        String foto = new File("Fotos de Placas").getAbsolutePath() 
        		+ System.getProperty("file.separator") + "DSC01312.jpg";
        System.out.println(foto);
        File file = new File(foto);
        System.out.println(file.getAbsolutePath());
        BufferedImage img = ImageIO.read(file);
        
        // LIMPAR SAIDA
        
        File sd = new File(debugVisitorDir);
        clearFolder(sd);
        
        // DEBUG
        
        DebugVisitorAnpr visitor = new DebugVisitorAnpr(debugVisitorDir);
        
        // PROCESSAR IMAGEM
        
        PlateRecognitionResult result = anpr.recognizePlate(img, visitor);
        
        System.out.println(result.getTime());
        System.out.println("aQUIUII " + result.getPlates());
        
        for(int i = 0; i < result.getPlates().length; i++) {
            try {
                File f = new File(sd.getCanonicalPath() + "\\p" + i + "=" +  result.getPlates()[i].getPlateString() + ".jpg");
                ImageIO.write(result.getPlates()[i].toImage(2, 20),"jpg",f);
            } catch(Exception e) {
                
            }
        }
    }
    
    public static PlateRecognizer createBRPlateRecognizer(OCRPlate ocrp) {
        
        // CONFIGURAÇÃO DO ANPR
        
        BPlateRecognizerProps props = new BPlateRecognizerProps();
        
        props.plateCharWidthMax = 20;
        props.plateCharWidthMin = 4;
        
        props.plateCharHeightMax = 26;
        props.plateCharHeightMin = 14;
        
        props.plateVertMaxDiff = 3;
        
        props.normalizeThresholding = 0.5f;
        props.adptiveThresholdingRadius = 5;
        
        props.plateHorzMaxDiff = (int)(props.plateCharWidthMax*1.2);
        props.plateHorzMinDiff = (int)(props.plateCharWidthMin*1.2);
        
        BPlateRecognizerBlock block1 = new BPlateRecognizerBlock();
        
        block1.numSegments = 3;
        block1.maxWidthDiffNextBlock = (int)(props.plateCharWidthMax*1.6);
        block1.minWidthDiffNextBlock = (int)(props.plateCharWidthMin*1.6);
        
        props.blocks.add(block1);
        
        BPlateRecognizerBlock block2 = new BPlateRecognizerBlock();
        
        block2.numSegments = 4;
        
        props.blocks.add(block2);
        
        // CRIAÇÃO DO ANRP
        
        PlateRecognizer recognizer = new BPlateRecognizer(ocrp,props);
        
        System.out.println(recognizer);
        
        return recognizer;
    }
    
    public static OCRecognizer createOCRecognizer(String alphabetDir, String debugVisitorDir) throws IOException {
        
        // OCR
        
        String alphabetKeys = "0123456789abcdefghijklmnopqrstuvwxyz";
        
        Vector<AlphabetChar> alphabet = new Vector();
        
        System.out.println(alphabetDir);
        
        for(int i = 0; i < alphabetKeys.length(); i++) {
            char c = alphabetKeys.charAt(i);
            AlphabetChar ac = new AlphabetChar();
            ac.setCharValue(c);
            
            File af = new File(alphabetDir + System.getProperty("file.separator") + c + "_10x16_bw.jpg");
            BufferedImage abic = ImageIO.read(af);
            ImageLayerData iac = ImageLayerData.extractBrightnessLayer(abic);
            
            iac = iac.adaptiveThresholding(5);
            iac = iac.trim(0.5f);
            
            ac.setImage(iac);
            
            alphabet.add(ac);
        }
        
        FeaturesPairExtractor pairExtractor = 
                new ImagePairExtractor(FeaturesExtractor.PointExtractor.instanceCenter,ImagePairExtractor.MAX_SIZE);
        FeaturesComparator comparator = EuclideanComparator.instance;
        
        SimpleRecognizer recognizer = new SimpleRecognizer(alphabet,
                new ImageFeaturesComparator(
                    pairExtractor, 
                    comparator));
        
        if(debugVisitorDir != null) {
            DebugVisitorComparator debugVisitor = new DebugVisitorComparator(debugVisitorDir);

            ((ImageFeaturesComparator)recognizer.getImageComparator()).setVisitor(debugVisitor);
        }
        
        return recognizer;
    }
    
    public static void clearFolder(File folder) {
        File[] toDel = folder.listFiles();
        for(int i = 0; i < toDel.length; i++) {
            if(toDel[i].isDirectory()) {
                clearFolder(toDel[i]);
                toDel[i].delete();
            } else
                toDel[i].delete();
        }
    }

}
